home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_PRO / VIEWS.ZIP;1 / CVDZIP.EXE / CVCLTREE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-09  |  6.2 KB  |  327 lines

  1. /*
  2.     cvcltree.cpp
  3.  
  4.     ClassTreeView--displays class hierarchy view
  5.  
  6.     C++/Views 2.0 Demo
  7.     Copyright (c) 1992, by Liant Software Corp.
  8.     ALL RIGHTS RESERVED.
  9.  
  10.     Revision History:
  11.     -----------------
  12. */
  13.  
  14. #include "cvcltree.h"
  15. #include "cvclinfo.h"
  16. #include "port.h"
  17. #include "brush.h"
  18. #include "font.h"
  19. #include "shade.h"
  20. #include "tagstrm.h"
  21.  
  22. #include <stdio.h>    // for sscanf()
  23.  
  24. #define    BOX_WIDTH        86
  25. #define    BOX_HEIGHT        18
  26.  
  27. defineClass(ClassTreeView, VView)
  28.  
  29. ClassTreeView::ClassTreeView()
  30. {
  31.     ;
  32. }
  33.  
  34. ClassTreeView::ClassTreeView(VFrame &f, VWindow *parent)
  35.     : VView(f, parent, StyleSizable)
  36. {
  37.     firstClass = 0;
  38.     lastClass = 0;
  39.     currClass = 0;
  40.  
  41.     selectMthd = 0;
  42.     client = 0;
  43.  
  44.     aPort = new VPort(this);
  45.     aFont = new VFont("Arial", 8);
  46.     aPort->useFont(aFont);
  47.  
  48.     setBackground(new VBrush(LightGray));
  49. }
  50.  
  51. ClassTreeView::~ClassTreeView()
  52. {
  53.     /* destroy background brush (if present) */
  54.     delete getBackground();
  55.  
  56.     delete aPort;
  57.     delete aFont;
  58.  
  59.     /* free list of classes */
  60.     reset();
  61. }
  62.  
  63. boolean ClassTreeView::free()
  64. {
  65.     delete this;
  66.     return(TRUE);
  67. }
  68.  
  69. void ClassTreeView::reset()
  70. {
  71.     ClassInfo *cinfo, *next;    
  72.  
  73.     /* free list of classes */
  74.     cinfo = firstClass;
  75.     while(cinfo) {
  76.         next = cinfo->getNext();
  77.         delete cinfo;
  78.         cinfo = next;
  79.     }
  80.  
  81.     firstClass = 0;
  82.     lastClass = 0;
  83.     currClass = 0;
  84. }
  85.  
  86. boolean ClassTreeView::loadFromStream(VStream &strm)
  87. /*
  88.     Load a class tree from the description in 'strm':
  89.  
  90.     (object      parent  40 250)
  91. */
  92. {
  93.     VTagStream    tagStrm;
  94.     VString        cmd;
  95.     char        name[60], parent[60];
  96.     int            x, y;
  97.  
  98.     reset();
  99.     tagStrm.beginScan(&strm, NIL);
  100.     tagStrm.tags('(', ')');
  101.  
  102.     while(tagStrm.getTag(cmd)) {
  103.         sscanf(cmd.gets(), "%s %s %d %d", name, parent, &x, &y);
  104.         add(name, parent, x, y);
  105.     }
  106.  
  107.     return(TRUE);
  108. }
  109.  
  110. void ClassTreeView::add(char *classname, char *parentname, int x, int y)
  111. /*
  112.     Add a class to the class list
  113. */
  114. {
  115.     ClassInfo  *cinfo;    
  116.  
  117.     if (!firstClass) {
  118.         /* create list of classes */
  119.         firstClass = new ClassInfo(classname, 0, x, y);
  120.         lastClass = firstClass;
  121.     }
  122.     else {
  123.         /* add new class to end of list */
  124.         lastClass = new ClassInfo(classname, lastClass, x, y);
  125.  
  126.         /* find parent class */
  127.         if (parentname) {
  128.             for(cinfo = firstClass; cinfo != 0; cinfo = cinfo->getNext()) {
  129.                 if (*(cinfo->getName()) == parentname) {
  130.                     lastClass->setParent(cinfo);
  131.                     break;
  132.                 }
  133.             }
  134.         }
  135.     }
  136. }
  137.  
  138. boolean ClassTreeView::paint()
  139. /*
  140.     Draw the class hierarchy view.
  141. */
  142. {
  143.     ClassInfo  *cinfo;    
  144.  
  145.     aPort->open();
  146.  
  147.     /* draw the classes */
  148.     for(cinfo = firstClass; cinfo != 0; cinfo = cinfo->getNext()) {
  149.  
  150.         /* draw connecting line to parent */
  151.         if (cinfo->getParent()) {
  152.             int xp = cinfo->getParent()->getX() + BOX_WIDTH / 2 + 1;
  153.             int yp = cinfo->getParent()->getY();
  154.             int xc = cinfo->getX() - BOX_WIDTH / 2;
  155.             int yc = cinfo->getY();
  156.             int xmid = (xc + xp) / 2;
  157.  
  158.             aPort->moveTo(xp, yp);
  159.             aPort->lineTo(xmid, yp);
  160.             aPort->lineTo(xmid, yc);
  161.             aPort->lineTo(xc, yc);
  162.         }
  163.  
  164.         /* draw boxes for the class */
  165.         drawClass(cinfo, aPort);
  166.     }
  167.  
  168.     aPort->close();
  169.  
  170.     return(TRUE);
  171. }
  172.  
  173. void ClassTreeView::drawClass(ClassInfo *cinfo, VPort *port)
  174. /*
  175.     Draw a single class button
  176. */
  177. {
  178.     VRectangle    rect;
  179.  
  180.     int xmin, ymin, xmax, ymax;
  181.  
  182.     xmin = cinfo->getX() - BOX_WIDTH / 2;
  183.     ymin = cinfo->getY() - BOX_HEIGHT / 2;
  184.     xmax = xmin + BOX_WIDTH;
  185.     ymax = ymin + BOX_HEIGHT;
  186.  
  187.     VPen pn;
  188.  
  189.     port->usePen(&pn);
  190.     port->useBrush(getBackground());
  191.  
  192.     pn.color(BLACK);
  193.     rect.set(Corners, xmin - 1, ymin - 1, xmax + 2, ymax + 2);
  194.     port->fillRegion(&rect);
  195.  
  196.     if (cinfo == currClass) {
  197.         pn.color(DarkGray);
  198.         port->moveTo(xmin, ymax);
  199.         port->lineTo(xmax, ymax);
  200.         port->lineTo(xmax, ymin);
  201.         port->lineTo(xmin, ymin);
  202.         port->lineTo(xmin, ymax);
  203.  
  204.         pn.color(LightGray);
  205.         port->moveTo(xmin + 1, ymax - 1);
  206.         port->lineTo(xmax - 1, ymax - 1);
  207.         port->lineTo(xmax - 1, ymin + 1);
  208.  
  209.         /* draw dotted line to indicate selected item */
  210. //        rect.set(CenterDim, cinfo->getX(), cinfo->getY(), BOX_WIDTH - 4, BOX_HEIGHT - 4);
  211. //        pn.color(BLACK);
  212. //        pn.pattern(DotLine);
  213. //        port->frameRegion(&rect);
  214.  
  215.  
  216.         rect.set(CenterDim, cinfo->getX() + 1, cinfo->getY() + 2, BOX_WIDTH, BOX_HEIGHT);
  217.     }
  218.     else {
  219.         pn.color(DarkGray);
  220.         port->moveTo(xmin, ymax);
  221.         port->lineTo(xmax, ymax);
  222.         port->lineTo(xmax, ymin);
  223.  
  224.         port->moveTo(xmin + 1, ymax - 1);
  225.         port->lineTo(xmax - 1, ymax - 1);
  226.         port->lineTo(xmax - 1, ymin + 1);
  227.  
  228.         pn.color(WHITE);
  229.         port->moveTo(xmax, ymin);
  230.         port->lineTo(xmin, ymin);
  231.         port->lineTo(xmin, ymax);
  232.  
  233.         rect.set(CenterDim, cinfo->getX(), cinfo->getY() + 1, BOX_WIDTH, BOX_HEIGHT);
  234.     }
  235.  
  236.     port->usePen(NIL);
  237.     port->useBrush(NIL);
  238.  
  239.     port->wrtText(cinfo->getName()->gets(), &rect, JustifyCenter);
  240. }
  241.  
  242. boolean ClassTreeView::mouseDn(int mx, int my)
  243. /*
  244.     Mouse button released in the class window
  245. */
  246. {
  247.     ClassInfo  *cinfo;
  248.     boolean        changed;
  249.  
  250.     if ((cinfo = pick(mx, my)) != 0) {
  251.         aPort->open();
  252.         changed = setCurrClass(cinfo, aPort);
  253.         aPort->close();
  254.  
  255.         if (changed) {
  256.             /* invoke callback method */
  257.             if (client && selectMthd != NIL_METHOD) {
  258.                 client->perform(selectMthd);
  259.             }
  260.         }
  261.     }
  262.  
  263.     return(TRUE);
  264. }
  265.  
  266. ClassInfo *ClassTreeView::pick(int mx, int my)
  267. /*
  268.     Test if point (mx, my) hits a class box.
  269.     If so return a pointer to the ClassInfo box, else 0
  270. */
  271. {
  272.     ClassInfo  *cinfo;    
  273.     VRectangle    rect;
  274.  
  275.     for (cinfo = firstClass; cinfo != 0; cinfo = cinfo->getNext()) {
  276.         rect.set(CenterDim, cinfo->getX(), cinfo->getY(), BOX_WIDTH, BOX_HEIGHT);
  277.         if (rect.pointIn(mx, my)) {
  278.             return(cinfo);
  279.         }
  280.     }
  281.  
  282.     return(0);
  283. }
  284.  
  285. boolean ClassTreeView::setCurrClass(ClassInfo *cinfo, VPort *port)
  286. /*
  287.     Make 'cinfo' the selected class...
  288.     Return TRUE if the current class changes
  289. */
  290. {
  291.     ClassInfo *old = currClass;
  292.     currClass = cinfo;
  293.  
  294.     if (old != currClass) {
  295.         if (port && old) {
  296.             /* repaint old box */
  297.             drawClass(old, port);
  298.         }
  299.         if (port && currClass) {
  300.             /* repaint new box */
  301.             drawClass(currClass, port);
  302.         }
  303.  
  304.         return(TRUE);
  305.     }
  306.  
  307.     return(FALSE);
  308. }
  309.  
  310. void ClassTreeView::uponClick(id clnt, method mthd) 
  311. /*
  312.     Attach a callback member to the treeview
  313. */
  314. {
  315.     if (clnt) {
  316.         client = clnt; 
  317.     }
  318.     if (mthd) {
  319.         selectMthd = mthd; 
  320.     }
  321.     if (!clnt || mthd == NIL_METHOD) {
  322.         client = NIL;
  323.         selectMthd = NIL;
  324.     }
  325. }
  326.  
  327.